package com.wyj.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;

public class SelectorServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 9999));
        serverSocketChannel.configureBlocking(false);

        //创建选择器
        Selector selector = Selector.open();
        //将服务端通道注册到选择器上，同时注册监听事件为连接事件
        SelectionKey register = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务端启动成功了···");
        while (true) {
            int select = selector.select(2000);
            if (select == 0) {
                continue;
            }
            //    获取到事件集合
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                //获取当前的连接事件并进行判断
                SelectionKey selectionKey = iterator.next();
                //处理连接事件
                if (selectionKey.isAcceptable()) {
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    System.out.println("客户端已经连接···");
                    //将通道设置为非阻塞，selector需要遍历监听
                    socketChannel.configureBlocking(false);
                    //将读就绪监听事件注册到selector中。此后将监听读就绪事件。
                    socketChannel.register(selector, SelectionKey.OP_READ);
                }
                //判断客户端的事件是否是读就绪事件。
                else if (selectionKey.isReadable()) {
                    //得到客户端通道
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    System.out.println("客户端读就绪事件···");
                    int read = socketChannel.read(byteBuffer);
                    if (read > 0) {
                        System.out.println("服务端接收到了消息：" + new String(byteBuffer.array(), 0, read, StandardCharsets.UTF_8));
                    }
                    socketChannel.write(ByteBuffer.wrap("这是服务端传给你的消息".getBytes(StandardCharsets.UTF_8)));
                    socketChannel.close();
                }

                //移除当前事件，避免重复处理
                iterator.remove();
            }
        }

    }
}
